#define DEF_ORG_FREQ_TABLE

#include "BuzzerMusic.h"
#include "Delay.h"
#include "LCD1602.h"

#define PER_TIME 64

uchar code Music[] = {
/*	// 1 4/4
	NO_EMPTY | M7, 2, NO_EMPTY | H2, 2, H3, 2,
	NO_EMPTY | H5_, 8 + 4, H5_, 16 * 2, P, 16,
	// 2
	NO_EMPTY | M3, 2, NO_EMPTY | M5_, 2, H2, 2,
	NO_EMPTY | H3, 2, NO_EMPTY | H5_, 2, H6_, 2,
	NO_EMPTY | HH2, 8, HH2, 16 * 2,*/ P, 8, M1, 4, M2, 4,
	// 3
	M3, 8, P, 8, P, 8, M2, 4, M3, 4, M5, 16, L7, 16,
	// 4
	L7, 8, M1, 8, P, 16, P, 16, P, 8, M1, 4, M2, 4,
	// 5
	M3, 8, P, 8, P, 8, M2, 4, M3, 4, M5, 16, L7, 16,
	// 6
	L7, 8, M1, 8, P, 16, P, 16, P, 8, M2, 4, M2, 4,
	// 7
	M3, 8, P, 8, P, 8, M3, 4, M2, 4, M3, 8, P, 8, P, 8, M2, 4, M2, 4,
	// 8
	M2, 8, M1, 8, P, 16, P, 16, P, 8, M1, 4, M2, 4,
	// 9
	M3, 8, P, 8, P, 8, M2, 4, M3, 4, M5, 16, M7, 16,
	// 10
	M7, 8, M6, 8 + 16 + 16, P, 16,
	// 11
	P, 8, M1, 8, M1, 8, M1, 8, M1, 8, L7, 8, M1, 8, M2, 4, NO_EMPTY | M3, 4,
	// 12
	M3, 16, P, 16, P, 16, M3, 8, M2, 8,
	// 13
	P, 8, M1, 8, M1, 8, M1, 8, M5, 8, M1, 8, M1, 8, L7, 4, NO_EMPTY | M1, 4,
	// 14
	M1, 16, P, 16, P, 16, P, 16,
	// 15
	P, 8, M3, 8, M3, 8, M3, 8, M3, 8, M2, 8, M1, 8, M2, 4, NO_EMPTY | M3, 4,
	// 16
	M3, 16, P, 8, H1, 8, M7, 8, M5, 8, M3, 8, M2, 4, NO_EMPTY | M1, 4,
	// 17
	M1, 8, P, 8, P, 8, M1, 8, L7, 8, M1, 8, M2, 8, M3, 4, NO_EMPTY | M3, 4,
	// 18
	M4, 16 * 2, M4, 8 + 4, NO_EMPTY | L7, 4, L7, 8, M4, 8,
	// 19
	M3, 16 * 3, P, 16,
	// 20
	P, 16 * 3 + 8, M2, 4, M2, 4,
	// 21
	M1, 8, L7, 4, NO_EMPTY | M1, 4, M1, 4, H1, 8, NO_EMPTY | M7, 4, M7, 16 + 8, M6, 8,
	// 22
	M5, 16, M3, 8, M2, 8, M2, 8, M1, 4, M1, 4, P, 8, M2, 4, M2, 4,
	// 23
	M1, 8, L7, 4, NO_EMPTY | M1, 4, M1, 4, H1, 8, NO_EMPTY | M7, 4, M7, 16 + 8, M6, 8,
	// 24
	M7, 16, M7, 8, H2, 8, H2, 8, H1, 4, H1, 4, P, 8, M2, 4, M2, 4,
	// 25
	M1, 8, L7, 4, NO_EMPTY | M1, 4, M1, 4, H1, 8, NO_EMPTY | M7, 4, M7, 16 + 8, M6, 8,
	// 26
	M5, 16, M3, 8, M2, 8, M2, 8, M3, 4, M1, 4, P, 8, L6, 4, L7, 4,
	// 27
	M1, 16 + 8, M3, 4, M2, 16 + 8, M1, 4, NO_EMPTY | M1, 4,
	// 28
	M1, 16 * 2, P, 16, P, 8, L6, 4, L7, 4,
	// 29
	M1, 16 + 8, M3, 8, M4, 8, M3, 8, M2, 8, M1, 4, NO_EMPTY | M3, 4,
	// 30
	M3, 16 * 4,
	// 31
	P, 16 * 3, P, 8, M1, 4, M2, 4,
	// 32
	H3, 16 * 2, H5, 16 * 2,
	
	// 33
	H3, 16 * 2, H2, 16, H1, 16,
	// 34
	M7, 16 * 2, M5_, 16 * 2,
	// 35
	H3, 16 * 2, H2, 16, H1, 16,
	// 36
	H5_, 16 * 2, H3, 16, H2, 16,
	// 37
	H1, 8, M4, 8, M4, 8, H1, 8, H2, 8, H1, 8, M7, 8, M6, 8,
	// 38
	M5_, 8, M7, 8, H2, 8, H4, 8, H3, 16, H2, 16,
	// 39
	H1, 16 * 2, H1, 8 + 4, NO_EMPTY | H2, 4, H2, 8, H4, 8,
	// 40
	H3, 16 * 4,
	// 41
	H5_, 16 * 4,

	// 42 2/4
	P, 16, P, 8, M2, 4, M2, 4,
	// 43 4/4
	M1, 8, L7, 4, NO_EMPTY | M1, 4, M1, 4, H1, 8, NO_EMPTY | M7, 4, M7, 16 + 8, M6, 8,
	// 44
	M5, 16, M3, 8, M2, 8, M2, 8, M1, 4, M1, 4, P, 8, M2, 4, M2, 4,
	// 45
	M1, 8, L7, 4, NO_EMPTY | M1, 4, M1, 4, H1, 8, NO_EMPTY | M7, 4, M7, 16 + 8, M6, 8,
	// 46
	M7, 16, M7, 8, H2, 8, H2, 8, H1, 4, H1, 4, P, 8, M2, 4, M2, 4,
	// 47
	M1, 8, L7, 4, NO_EMPTY | M1, 4, M1, 4, H1, 8, NO_EMPTY | M7, 4, M7, 16 + 8, M6, 8,
	// 48
	M5, 16, M3, 8, M2, 8, M2, 8, M3, 4, M1, 4, P, 8, L6, 4, L7, 4,
	// 49
	M1, 16 + 8, M3, 8, M2, 16 + 8, M1, 4, NO_EMPTY | M1, 4,
	// 50
	M1, 16 * 2, P, 16, P, 8, L6, 2, L7, 2,
	// 51
	M1, 16 + 8, M3, 8, M4, 8, M3, 8, M2, 8, M1, 4, NO_EMPTY | M3, 4,
	// 52
	M3, 16 * 3, P, 16,

	// 53
	P, 16 * 3, P, 8, M1, 4, M2, 4,
	// 54
	M3, 8, P, 8, P, 8, M2, 4, M2, 4, M5, 16, L7, 16,
	// 55
	L7, 8, M1, 8, P, 16 * 2, P, 8, M1, 4, M2, 4,

	// 56
	M3, 8, P, 8, P, 8, M2, 4, M3, 4, M5, 16, L7, 16,
	// 57
	L7, 8, M1, 8, P, 16 * 2, P, 8, M2, 4, M2, 4,
	// 58
	M3, 8, P, 8, P, 8, M3, 4, M2, 4, M3, 8, P, 8, P, 8, M2, 4, M2, 4,
	// 59
	M2, 8, M1, 8, P, 16 * 2, P, 8, M1, 4, M2, 4,
	
	// 60
	M3, 8, P, 8, P, 8, M2, 4, M3, 4, M5, 16, M7, 16,
	// 61
	M7, 16, NO_EMPTY | M6, 16, M6, 16 * 4, 

	P, 64
};

uint musicCnt = sizeof(Music) / sizeof(uchar);
uint musicInd, musicFreq;
uint musicMineute, musicSecond, musicMs;

void main() {
	uint musicDelay = 0, musicDelayEnd, freqSelect;
	uchar noDelay = 0;

	TMOD = 0x01;
	TF0 = 0;
	TR0 = 1;
	TH0 = 0xFF;
	TL0 = 0xFF;
	ET0 = 1;
	PT0 = 0;
	
	EA = 1;

	LCD_Init();
	LCD_ShowString(1, 5, "Hz");
	LCD_ShowString(2, 1, "00:00");

	while(1) {
		if(musicInd < musicCnt) {
			freqSelect = Music[musicInd++];
			noDelay = (freqSelect & 0x80) == 0x80;
			musicFreq = FreqTable[freqSelect & 0x7F];
			musicDelay = Music[musicInd++] / 2 * PER_TIME;
			musicDelayEnd = musicDelay / 6;
			
			musicMs += musicDelay;
			while(musicMs >= 1176) {
				musicSecond++;
				musicMs -= 1176;
				LCD_ShowNum(2, 4, musicSecond, 2);
				musicDelay -= 8;
			}
			while(musicSecond >= 60) {
				musicMineute++;
				musicSecond -= 60;
				LCD_ShowNum(2, 4, musicSecond, 2);
				LCD_ShowNum(2, 1, musicMineute, 2);
				musicDelay -= 16;
			}

			if(!noDelay)
				musicDelay -= musicDelayEnd;
			LCD_ShowNum(1, 1, OrgFreqTable[freqSelect], 4);

			if(!P3_3) {
				musicDelay /= 4;
				musicDelayEnd /= 4;
			}
			Delay(musicDelay - 8);
			if(!noDelay) {
				TR0 = 0;
				Delay(musicDelayEnd);
				TR0 = 1;
			}
		}
	}
}

sbit BUZZER = P1^5;
void Timer0_Routine() interrupt 1
{
	if(musicFreq) {
		 TH0 = musicFreq / 256;
		 TL0 = musicFreq % 256;
		 BUZZER = !BUZZER;
	}
}